<?php
declare (strict_types = 1);

namespace app\index\controller;

use app\index\model\Block;
use app\index\model\User;
use app\common\model\user\SignForm;
use app\index\BaseController;
use app\index\model\Article;
use think\Exception;
use think\exception\ValidateException;
use app\common\validate\Register;
use app\common\validate\Login;
use app\index\model\Topic;

class Index extends BaseController
{
    //中间件
    protected $middleware = [
        'method:ajax' => ['only'=>['sendCaptcha','signup','signin','sendResetPasswordToken','resetPassword']],
        'access:@' => ['only'=>['logout']],
        'access:?' => ['only'=>[
            'forget',
            'sendResetPasswordToken',
            'showResetPassword',
            'resetPassword',
            'login',
            'signin',
            'register',
            //'sendCaptcha',
            'signup',
        ]],
    ];


    //更多热门
    public function hot(){
        return view('hot',[
            'count' => Article::getHotCount(),
            'limit' => Article::LIMIT_NUM,

            'crumb' => [
                'home'     => '/',
                '热门文章'  => request()->url()
            ],

            //*热门文章
            'activeArticles' => Block::getActiveArticles(),
            //热门标签
            'activeTags' => Block::getActiveTags(),
            //*推荐作者
            'activeAuthors' => Block::getActiveAuthors(),
            //*推荐话题
            'activeTopics' => Block::getActiveTopics(),
        ]);
    }

    //更多推荐
    public function best(){
        return view('best',[
            'count' => Article::getCount(['best'=>Article::BEST_YES]),
            'limit' => Article::LIMIT_NUM,
            'where' => jsonStr(['best'=>Article::BEST_YES]),

            'crumb' => [
                'home'     => '/',
                '精品推荐'  => request()->url()
            ],

            //*热门文章
            'activeArticles' => Block::getActiveArticles(),
            //热门标签
            'activeTags' => Block::getActiveTags(),
            //*推荐作者
            'activeAuthors' => Block::getActiveAuthors(),
            //*推荐话题
            'activeTopics' => Block::getActiveTopics(),
        ]);
    }

    //首页
    public function index()
    {
        return view('index',[
            //精品推荐
            'bests' => Article::getBests(),

            //热门话题
            'topics' => jsonStr(Topic::getHotTopics()),
            'topicLimit' => Topic::HOT_LIMIT,

            //文章列表
            'count' => Article::getCount(),
            'limit' => Article::LIMIT_NUM,

            //面包屑
            'crumb' => [
                'home'     => request()->url(),
            ],



            //*热门文章
            'activeArticles' => Block::getActiveArticles(),
            //热门标签
            'activeTags' => Block::getActiveTags(),
            //*推荐作者
            'activeAuthors' => Block::getActiveAuthors(),
            //*推荐话题
            'activeTopics' => Block::getActiveTopics(),
        ]);
    }

    //登出操作
    public function logout(){
        app()->user->logout();
        return redirect((string) url('index'));
    }

    //忘记密码
    public function forget(){
        return view('forget');
    }

    //发送重置密码连接
    public function sendResetPasswordToken(){
        try{
            //验证数据
            $data = request()->only(['username','email']);

            validate([
                'username'=> 'require|max:15',
                'email'   => 'require|max:64|email',
            ])->check($data);

            if ( !SignForm::sendResetPasswordToken($data['username'], $data['email']) ){
                throw new Exception('发送失败.');
            }

        } catch (ValidateException $e) {
            //验证错误
            return json(['code'=>1,'msg'=>$e->getMessage()]);
        } catch (\Exception $e){
            //系统错误
            //Log::error($this->request->completePathInfo(true) . ' : ' .$e->getMessage());
            return json(['code'=>1,'msg'=>$e->getMessage()]);
        }
        return json(['code'=>0,'msg'=>'发送成功.','url'=>(string) url('index')]);
    }

    //重置密码页面
    public function showResetPassword(){
        $token = $this->request->param('token');

        //根据token获取用户
        $user = User::getIdentityByResetPasswordTokenCrypt($token);

        //token错误
        if (!$user) abort(404,'连接无效');
        return view('reset',[
            'token' => $token
        ]);
    }

    //重置密码
    public function resetPassword(){
        try{

            //接收参数
            $data = request()->only(['token','password','re_password']);
            //验证参数
            validate([
                'token'   => 'require',
                'password'          => 'require|min:6',
                're_password'       => 'confirm:password',
            ],[
                'token.require' => '参数错误',
                'password.require' => '密码必须',
                'password.min' => '密码最小6位字符',
                're_password.confirm' => '两次密码不一致',
            ])->check($data);

            //根据token获取用户
            $user = User::getIdentityByResetPasswordTokenCrypt($data['token']);
            $user->setAttr('password_hash',User::generatePasswordHash($data['password']));

            //保存到数据库
            if (!$user->save()) throw new Exception('重置失败.');

        } catch (ValidateException $e) {
            //验证错误
            return json(['code'=>1,'msg'=>$e->getMessage()]);
        } catch (\Exception $e){
            //系统错误
            //Log::error($this->request->completePathInfo(true) . ' : ' .$e->getMessage());
            return json(['code'=>1,'msg'=>$e->getMessage()]);
        }
        return json(['code'=>0,'msg'=>'重置密码成功.','url'=>(string)url('login')]);
    }

    //登录操作
    public function login(){
        return view('login');
    }

    //登录操作
    public function signin(){
        try{
            //验证数据
            $data = request()->only(['account','password','captcha','remember']);

            validate(Login::class)->check($data);

            if ( !SignForm::signin($data['account'], $data['password'], isset($data['remember'])) ){
                throw new Exception('登录失败.');
            }

        } catch (ValidateException $e) {
            //验证错误
            return json(['code'=>1,'msg'=>$e->getMessage()]);
        } catch (\Exception $e){
            //系统错误
            //Log::error($this->request->completePathInfo(true) . ' : ' .$e->getMessage());
            return json(['code'=>1,'msg'=>$e->getMessage()]);
        }
        return json(['code'=>0,'msg'=>'登录成功.','url'=>app()->user->getReturnUrl()]);
    }

    //注册
    public function register(){
        return view('register');
    }

    //发送邮箱验证码
    public function sendCaptcha(){
        try{
            //接受数据
            $data = request()->only(['email']);
            //验证
            validate(['email'=>'require|max:64|email'])->check($data);

            //发送邮件验证码
            if ( !SignForm::sendMail($data['email']) ){
                throw new Exception('验证码发送失败,请重试.');
            }


        }catch (\Exception $e){
            //Log::error($this->request->completePathInfo(true) . ' : ' .$e->getMessage());
            return json([
                'code'=>1,
                'msg'=>$e->getMessage()
            ]);
        }
        return json([
            'code'=>0,
            'msg'=>'发送邮件成功.'
        ]);
    }

    //注册用户
    public function signup(){
        try{
            //验证数据
            $data = request()->only(['username','email','captcha','password','re_password']);

            validate(Register::class)->check($data);

            $user = $this->getModel(User::class);

            //生成密码
            $data = array_merge($data, [
                'password_hash' => User::generatePasswordHash($data['password']),
                //'auth_key' => User::generateAuthKey(),
            ]);

            if( !$user->save($data) )
                throw new Exception('注册失败.');


        } catch (ValidateException $e) {
            //验证错误
            return json(['code'=>1,'msg'=>$e->getMessage()]);
        } catch (\Exception $e){
            //系统错误
            //Log::error($this->request->completePathInfo(true) . ' : ' .$e->getMessage());
            return json(['code'=>1,'msg'=>$e->getMessage()]);
        }
        return json(['code'=>0,'msg'=>'注册成功.','url'=>(string)url('login')]);

    }
}
